// Rebuilder.cpp: implementation of the Rebuilder class.
//
//////////////////////////////////////////////////////////////////////

#include "Rebuilder.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////


//inicializacion
int Rebuilder::posicion = 0;


//PROTOCOLO
//cantidad figuras + [enum tipo figura + size de struct + struct + textura]*figura
//es asi?

void Rebuilder::convertFiguras(char* stream, listaFiguras* lista) {
	//esta variable sera el puntero del stream, lo reseteo 
	//cuando empiezo cada conversion
	Rebuilder::posicion = 0;

	int i = 0;
	//traigo la cantidad de figuras del stream
	int cantidadFiguras = Rebuilder::getEntero(stream);
	
	while (i < cantidadFiguras) {

		int tipo = Rebuilder::getEntero(stream);

		figura* fig;
		
		switch (tipo) {
		
			case CIRCULO:
				fig = Rebuilder::reconstruirCirculo(stream);
				logger::getInstancia()->logCliente("REBUILDER :: CIRCULO");
				break;
			case RECTANGULO:
				fig = Rebuilder::reconstruirRectangulo(stream);
				logger::getInstancia()->logCliente("REBUILDER :: RECTANGULO");
				break;
			case SEGMENTO:
				fig = Rebuilder::reconstruirSegmento(stream);
				logger::getInstancia()->logCliente("REBUILDER :: SEGMENTO");
				break;
			case TRIANGULO:
				fig = Rebuilder::reconstruirTriangulo(stream);
				logger::getInstancia()->logCliente("REBUILDER :: TRIANGULO");
				break;
			default:
				throw new errorInesperadoException("procesarColision::tipo desconocido de figura en el rebuilder");


		}

		lista->push_back(fig);
		i++;

	}

}



figura* Rebuilder::reconstruirCirculo(char* stream) {
	SocketCirculo socketCirculo;
	int sizeStruct = Rebuilder::getEntero(stream);

	memcpy(reinterpret_cast<char*>(&socketCirculo), stream + Rebuilder::posicion,sizeStruct);	
	
	Rebuilder::posicion += sizeStruct;
	textura* tex = Rebuilder::getTextura(stream,socketCirculo.textura);
	
	color* colorRelleno = new color(socketCirculo.colorRellenoGrafico.getAzul(),socketCirculo.colorRellenoGrafico.getRojo(),socketCirculo.colorRellenoGrafico.getVerde());
	color* colorBorde = new color(socketCirculo.colorBordeGrafico.getAzul(),socketCirculo.colorBordeGrafico.getRojo(),socketCirculo.colorBordeGrafico.getVerde());
	circulo* circ = new circulo(tex,colorRelleno,colorBorde);
	punto puntoCirculo(socketCirculo.centro.getX(),socketCirculo.centro.getY());
	circ->setCentro(puntoCirculo);
	float radioCirculo = socketCirculo.radio;
	circ->setRadio(radioCirculo);
	
	return circ;

}



figura* Rebuilder::reconstruirTriangulo(char* stream) {
	SocketTriangulo socketTriangulo;
	int sizeStruct = Rebuilder::getEntero(stream);

	memcpy(reinterpret_cast<char*>(&socketTriangulo), stream + Rebuilder::posicion,sizeStruct);	
	
	Rebuilder::posicion += sizeStruct;
	
	textura* tex = Rebuilder::getTextura(stream,socketTriangulo.textura);
	
	color* colorRelleno = new color(socketTriangulo.colorRellenoGrafico.getAzul(),socketTriangulo.colorRellenoGrafico.getRojo(),socketTriangulo.colorRellenoGrafico.getVerde());
	color* colorBorde = new color(socketTriangulo.colorBordeGrafico.getAzul(),socketTriangulo.colorBordeGrafico.getRojo(),socketTriangulo.colorBordeGrafico.getVerde());
	
	triangulo* tri = new triangulo(tex,colorRelleno,colorBorde);

	punto puntoA(socketTriangulo.puntoA.getX(),socketTriangulo.puntoA.getY());
	punto puntoB(socketTriangulo.puntoB.getX(),socketTriangulo.puntoB.getY());
	punto puntoC(socketTriangulo.puntoC.getX(),socketTriangulo.puntoC.getY());

	tri->setPuntoA(puntoA);
	tri->setPuntoB(puntoB);
	tri->setPuntoC(puntoC);

	return tri;
}


figura* Rebuilder::reconstruirRectangulo(char* stream) {
	SocketRectangulo socketRectangulo;
	int sizeStruct = Rebuilder::getEntero(stream);

	memcpy(reinterpret_cast<char*>(&socketRectangulo), stream + Rebuilder::posicion,sizeStruct);	
	
	Rebuilder::posicion += sizeStruct;
	
	textura* tex = Rebuilder::getTextura(stream,socketRectangulo.textura);
	
	color* colorRelleno = new color(socketRectangulo.colorRellenoGrafico.getAzul(),socketRectangulo.colorRellenoGrafico.getRojo(),socketRectangulo.colorRellenoGrafico.getVerde());
	color* colorBorde = new color(socketRectangulo.colorBordeGrafico.getAzul(),socketRectangulo.colorBordeGrafico.getRojo(),socketRectangulo.colorBordeGrafico.getVerde());
	
	rectangulo* rect = new rectangulo(tex,colorRelleno,colorBorde);
	punto puntoRect(socketRectangulo.puntoInicial.getX(),socketRectangulo.puntoInicial.getY());
	rect->setPuntoInicial(puntoRect);
	rect->setAlto(socketRectangulo.alto);
	rect->setAncho(socketRectangulo.ancho);

	return rect;
}



figura* Rebuilder::reconstruirSegmento(char* stream) {
	SocketSegmento socketSegmento;
	int sizeStruct = Rebuilder::getEntero(stream);

	memcpy(reinterpret_cast<char*>(&socketSegmento), stream + Rebuilder::posicion,sizeStruct);	
	
	Rebuilder::posicion += sizeStruct;
	
	color* colorBorde = new color(socketSegmento.colorBordeGrafico.getAzul(),socketSegmento.colorBordeGrafico.getRojo(),socketSegmento.colorBordeGrafico.getVerde());
	
	segmento* seg = new segmento(NULL,colorBorde,colorBorde);

	punto puntoIni(socketSegmento.puntoInicial.getX(),socketSegmento.puntoInicial.getY());
	punto puntoFin(socketSegmento.puntoFinal.getX(),socketSegmento.puntoFinal.getY());
	seg->setPuntoFinal(puntoFin);
	seg->setPuntoInicial(puntoIni);

	return seg;
}


int Rebuilder::getEntero(char* stream) {
	return Rebuilder::getEntero(stream,Rebuilder::posicion);
}


int Rebuilder::getEntero(char* stream, long& pointer) {
	int ret;
	memcpy(&ret,stream + pointer,sizeof(long));
	pointer += sizeof(long);
	return ret;
}

int Rebuilder::getEntero(char* stream, int& pointer) {
	int ret;
	memcpy(&ret,stream + pointer,sizeof(int));
	pointer += sizeof(int);
	return ret;
}




textura* Rebuilder::getTextura(char* stream,int sizeTextura) {
	textura* ret = NULL;
	//si no es cero, tengo que recibir el path de la textura
	if ( sizeTextura != 0) {
		char* pathTextura = (char*)malloc(sizeTextura + 1);
		pathTextura[sizeTextura] = '\0';
		memcpy(pathTextura,stream + Rebuilder::posicion,sizeTextura);
		Rebuilder::posicion += sizeTextura;
		std::string stringPath(pathTextura);
		try {
			ret = new textura(stringPath);
		} catch (noImageFoundException* e) {
			ret = NULL;
			logger::getInstancia()->logCliente("No se encontro imagen. No se pudo cargar textura " + stringPath);
			delete(e);
		}
	}

	return ret;
}



//cantidad figuras + [enum tipo figura + size de struct + struct + textura]*figura
char* Rebuilder::getCharAsteriscoMocked() {
	int pos = 0;
	char* cadena = (char*)malloc(2048);

	//cant figuras
	int cantFiguras = 2;

	memcpy(cadena + pos,&cantFiguras,sizeof(int));
	pos = pos + sizeof(int);
	
	//tipofigura
	tipoFigura tipo =  CIRCULO;
	memcpy(cadena + pos,&tipo,sizeof(int));
	pos = pos + sizeof(int);

	//socket circulo con textura
	SocketCirculo socketCirculo;
	socketCirculo.centro = punto(66,33);
	socketCirculo.radio = 120;
	socketCirculo.textura = 11;
	socketCirculo.colorBordeGrafico = color(100,100,100);
	socketCirculo.colorRellenoGrafico = color(100,100,100);
	int sizeOfStruct = sizeof(SocketCirculo);
	memcpy(cadena+pos,&sizeOfStruct,sizeof(int));
	pos = pos + sizeof(int);
	memcpy(cadena + pos, &socketCirculo, sizeOfStruct);
	pos = pos + sizeOfStruct;

	//textura de la fig 1
	char* text="textura.gif";
	int sizeTex = strlen(text);
	memcpy(cadena + pos, text,sizeTex);
	pos += 	sizeTex;


	//tipo figura 2
	tipoFigura tipo2 =  CIRCULO;
	memcpy(cadena + pos,&tipo2,sizeof(int));
	pos = pos + sizeof(int);

	//socket circulo con textura
	SocketCirculo socketCirculo2;
	socketCirculo2.centro = punto(69,44);
	socketCirculo2.radio = 169;
	socketCirculo2.textura = 0;
	socketCirculo2.colorBordeGrafico = color(55,1,133);
	socketCirculo2.colorRellenoGrafico = color(77,2,144);
	//size del struct
	int sizeOfStruct2 = sizeof(SocketCirculo);
	memcpy(cadena+pos,&sizeOfStruct2,sizeof(int));
	pos = pos + sizeof(int);
	//el struct en si
	memcpy(cadena + pos, &socketCirculo2, sizeOfStruct2);
	pos = pos + sizeOfStruct2;


	return cadena;

}



